package com.game.base.x5.web;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Build;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;

import com.game.base.R;
import com.game.base.app.base.BasePanel;
import com.game.base.databinding.CommonWebPanelBinding;
import com.game.base.utils.NetworkUtil;
import com.game.base.utils.file.FileUtil;
import com.game.base.utils.log.Logger;
import com.game.base.x5.web.util.WebListener;
import com.game.base.x5.web.util.WebLoadStatus;
import com.game.base.x5.web.util.WebUtil;
import com.game.base.x5.web.util.WebViewLifeCycle;
import com.tencent.smtt.export.external.interfaces.SslError;
import com.tencent.smtt.export.external.interfaces.SslErrorHandler;
import com.tencent.smtt.export.external.interfaces.WebResourceError;
import com.tencent.smtt.export.external.interfaces.WebResourceRequest;
import com.tencent.smtt.sdk.WebBackForwardList;
import com.tencent.smtt.sdk.WebChromeClient;
import com.tencent.smtt.sdk.WebView;
import com.tencent.smtt.sdk.WebViewClient;

/**
 * webView 处理模块
 */
public class WebPanel extends BasePanel<CommonWebPanelBinding> implements View.OnClickListener {

    private String url;
    private String data;                    // Html标签内容
    private boolean isLoadError = false;      //是否加载出错
    private boolean outSide = false;        // 外部浏览器显示

    public WebPanel(Activity activity, String url, String data) {
        super(activity);
        this.url = url;
        this.data = data;
        initView();
    }

    @Override
    protected int getLayoutId() {
        return R.layout.common_web_panel;
    }

    @SuppressLint("SetJavaScriptEnabled")
    private void initView() {
        binding.setClick(this);
        binding.customFrameLayout.show(R.id.emptyView);
        binding.emptyView.show(true);

        WebUtil.initWebSettings(binding.webView);
        binding.webView.setWebViewClient(new WebViewClient() {
            /**
             * 重定向
             */
            @Override
            public boolean shouldOverrideUrlLoading(WebView webView, String url) {
                // 外部浏览器打开; 不拦截apk下载地址
                if (url.toLowerCase().endsWith(".apk")) {
                    WebUtil.openUrlOnBrowser(getActivity(), url);
                    return true;
                }

                if (FileUtil.isPic(url)) {  // 图片
                    Logger.d(url);
                }

                webView.loadUrl(url);  // 不调用系统浏览器， 而是在本WebView中显示
                return true;
            }

            @Override
            public void onReceivedError(WebView webView, int errorCode, String description, String failingUrl) {
                super.onReceivedError(webView, errorCode, description, failingUrl);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    return;
                }
                showError(failingUrl);
            }

            // [https://www.jianshu.com/p/fcebd23cbebb]
            @TargetApi(Build.VERSION_CODES.M)
            @Override
            public void onReceivedError(WebView webView, WebResourceRequest webResourceRequest, WebResourceError webResourceError) {
                super.onReceivedError(webView, webResourceRequest, webResourceError);
                if (webResourceRequest.isForMainFrame()) {
                    showError(webResourceRequest.getUrl().toString());
                }
            }

            @Override
            public void onPageFinished(WebView webView, String url) {
                // [单独处理url为空的情况](https://stackoverflow.com/questions/30426017/webview-clicking-on-link-results-in-aboutblank?rq=1)
                if ("about:blank".equals(url) && webView.getTag() != null) {
                    webView.loadUrl(webView.getTag().toString());
                } else {
                    webView.setTag(url);
                }
                if (!isLoadError) {
                    binding.customFrameLayout.show(R.id.webView);
                }
                if (webListener != null)
                    webListener.onLoadFinish(WebLoadStatus.FINISH);
            }

            @Override
            public void onPageStarted(WebView webView, String url, Bitmap bitmap) {
                super.onPageStarted(webView, url, bitmap);
                isLoadError = false;
                binding.customFrameLayout.show(R.id.emptyView);
                binding.emptyView.show(true);
            }

            @Override
            public void onReceivedSslError(WebView webView, SslErrorHandler sslErrorHandler, SslError sslError) {
                sslErrorHandler.proceed();
            }
        });

        binding.webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onReceivedTitle(WebView webView, String s) {
                super.onReceivedTitle(webView, s);
                if (webListener != null)
                    webListener.onTitle(s);
            }
        });

        binding.webView.requestFocus();
        loadUrl();
    }

    private void showError(String failUrl) {
        url = failUrl;
        isLoadError = true;
        binding.customFrameLayout.show(R.id.emptyView);
        binding.emptyView.show(false, "加载失败", null, "点击重试", v -> loadUrl());
        if (webListener != null)
            webListener.onLoadFinish(WebLoadStatus.ERROR);

        Logger.d("Finish  error");
    }

    @Override
    public void onClick(View v) {
    }

    private void loadUrl() {
        // 判断有无网络
        binding.customFrameLayout.show(R.id.emptyView);
        if (!NetworkUtil.isConnected(getActivity())) {
            binding.emptyView.show(false, "网络连接失败", null, "点击重试", v -> loadUrl());
        } else {
            binding.emptyView.show(true);

            if (!TextUtils.isEmpty(url)) {
                binding.webView.loadUrl(url);
                return;
            }

            if (!TextUtils.isEmpty(data)) {
                binding.webView.loadDataWithBaseURL(null, data, "text/html", "UTF-8", null);
            }
        }
    }

    /**
     * @return 获取展示的WebView实例
     */
    public WebViewLifeCycle getWebView() {
        return new WebViewLifeCycle() {
            @Override
            public void onResume() {
                binding.webView.onResume();
                binding.webView.resumeTimers();
            }

            @Override
            public void onPause() {
                binding.webView.onPause();
                binding.webView.pauseTimers();
            }

            @Override
            public void onBackPressed() {
                binding.webView.goBack();
            }
        };
    }

    /**
     * 清除webView引用并置空，最好在引用webPanel页面的super.onDestroy()之前进行调用
     */
    public void onDestroy() {
        if (binding.webView != null) {
            binding.webView.removeJavascriptInterface("Android");
            binding.webView.removeAllViews();
            binding.webView.destroy();
        }
    }

    /**
     * @return 判断webView是否可以回退，并维护内部回退逻辑
     */
    public boolean canGoBack() {
        WebBackForwardList history = binding.webView.copyBackForwardList();
        int index = -1;
        String url = null;

        while (binding.webView.canGoBackOrForward(index)) {
            if (!history.getItemAtIndex(history.getCurrentIndex() + index).getUrl().equals("about:blank")) {
                binding.webView.goBackOrForward(index);
                url = history.getItemAtIndex(-index).getUrl();
                break;
            }
            index--;
        }
        return url != null;
    }

    private WebListener webListener;

    /**
     * 设置网页标题监听
     */
    public void setWebListener(WebListener webListener) {
        this.webListener = webListener;
    }
}
